package com.airlines.crewassignment.service.linkline.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.airlines.base.config.datasource.PrimaryDataSourceConfig;
import com.airlines.base.config.response.ResponseResult;
import com.airlines.base.config.response.ResponseResultBuilder;
import com.airlines.base.entity.dict.Select2;
import com.airlines.common.DateTimeRangeUtil;
import com.airlines.common.ListSortUtil;
import com.airlines.common.TimeUtil;
import com.airlines.crewassignment.constant.BaseConstant;
import com.airlines.crewassignment.constant.CrewConstant;
import com.airlines.crewassignment.constant.LinkLineConstant;
import com.airlines.crewassignment.dao.FlightInfoMapper;
import com.airlines.crewassignment.dao.LinkLineMapper;
import com.airlines.crewassignment.dao.basicinfo.AirPlaneMapper;
import com.airlines.crewassignment.domain.DateTimeRange;
import com.airlines.crewassignment.domain.FlightInfo;
import com.airlines.crewassignment.domain.LinkLine;
import com.airlines.crewassignment.domain.util.DutyDurationUtil;
import com.airlines.crewassignment.domain.util.FlightDurationUtil;
import com.airlines.crewassignment.entity.linkline.LinkLineEntity;
import com.airlines.crewassignment.entity.linkline.TaskLoop;
import com.airlines.crewassignment.entity.linkline.TaskLoopFlightFact;
import com.airlines.crewassignment.entity.linkline.fullcalendar.Event;
import com.airlines.crewassignment.entity.linkline.fullcalendar.EventForFlight;
import com.airlines.crewassignment.entity.linkline.fullcalendar.Resource;
import com.airlines.crewassignment.service.airport.AirportService;
import com.airlines.crewassignment.service.basicinfo.FoundationService;
import com.airlines.crewassignment.service.dict.Select2Service;
import com.airlines.crewassignment.service.linkline.FlightInfoService;
import com.airlines.crewassignment.service.linkline.FullCalendarService;
import com.airlines.crewassignment.service.linkline.LinkLineAService;
import com.airlines.crewassignment.service.linkline.LinkLineCService;
import com.airlines.crewassignment.service.linkline.LinkLineFService;
import com.airlines.crewassignment.service.linkline.PositionService;
import com.airlines.crewassignment.service.linkline.TaskLoopFlightFactService;

/**
 * @author xxxx
 * @date 2018年6月14日 
 * @description
 */
@Service
public class FullCalendarServiceImpl implements FullCalendarService{
	@Autowired
	private LinkLineMapper linkLineMapper;
	@Autowired
	private FlightInfoMapper flightInfoMapper;
	@Autowired
	private FlightInfoService flightInfoService;
	@Autowired
	private AirportService	airprotService;
	@Autowired
	private LinkLineFService linkLineFService;
	@Autowired
	private LinkLineCService linkLineCService;
	@Autowired
	private LinkLineAService linkLineAService;
	@Autowired
	private Select2Service select2Service;
	@Autowired
	private PositionService positionService;
	@Autowired
	private TaskLoopFlightFactService taskLoopFlightFactService;
	@Autowired
	private FoundationService foundationService;
	@Autowired
	private AirPlaneMapper airPlaneMapper;


	@Override
	public List<Resource> listResource(String dutyCode, Date flightDate) {
		LinkLineEntity query = new LinkLineEntity();
		query.setFlightDate(flightDate);
		query.setDutyCode(dutyCode);
		
		List<LinkLine> list =  linkLineMapper.listLinkLineBase(query);	
		
		ListSortUtil.sort(list, true, "crewLinkLineNo");
		List<Resource> rList = new ArrayList<>();
		for(LinkLine l : list ){
			Resource r = this.getResourceByLinkLine(l);
			rList.add(r);
		}
		return rList;
	}
	private Resource getResourceByLinkLine(LinkLine l ){
		Resource r = new Resource();
		r.setId(l.getCrewLinkLineNo().toString());
//		String dOrI = "";
//		if(StringUtils.equals("D", l.getDOrI())){
//			dOrI = LinkLineConstant.DI_D_NAME;
//		}
//		if(StringUtils.equals("I", l.getDOrI())){
//			dOrI = LinkLineConstant.DI_I_NAME;
//		}
		r.setCrewLinkLineAndDorI(l.getCrewLinkLineNo()+"");
		r.setAcTypeAndAcReg(l.getAcType());
		
		DateTimeRange flyDuration = new DateTimeRange(l.getTd(),l.getTa());
		//DateTime dutyTd = new DateTime(l.getTd()).minusMinutes(90);
		//DateTimeRange dutyDuration = new DateTimeRange(dutyTd.toDate(),l.getTa());
		r.setFlyAndDutyDuration(flyDuration.getHHmm());
		r.setTd(l.getTd());
		r.setTa(l.getTa());
		r.setTdHHmm(TimeUtil.getHHmm(l.getTd()));
		r.setTaHHmm(TimeUtil.getHHmm(l.getTa()));
		return r;
	}

	@Override
	public List<Event> listEvent(String dutyCode, Date flightDate) {
		LinkLineEntity query = new LinkLineEntity();
		query.setFlightDate(flightDate);
		query.setDutyCode(dutyCode);
		List<LinkLine> list =  linkLineMapper.listLinkLineBase(query);
		
		List<Event> eList = new ArrayList<>();
		for(LinkLine l : list ){
			Event e = this.getEventByLinkLine(l);
			eList.add(e);
		}
		return eList;
	}

	private Event getEventByLinkLine(LinkLine l){
		Event e = new Event();
		e.setId(l.getCrewLinkLineId().toString());
		e.setResourceId(l.getCrewLinkLineNo().toString());
		e.setFlightDate(l.getFlightDate());
		e.setStart(l.getTd());
		e.setEnd(l.getTa());
		String title = l.getFlightCom()+l.getFlightVoyage();
		e.setTitle(title);
		e.setFlightCom(l.getFlightCom());
		e.setFlightVoyage(l.getFlightVoyage());
		return e;
	}
	@Override
	public List<FlightInfo> listFlightNotHaveCrewLinkLine(String dutyCode, Date flightDate) {
		return flightInfoMapper.listFlightNotHaveCrewLinkLine(dutyCode,flightDate);
	}

	@Override
	public List<FlightInfo> listFlight(String dutyCode, Date flightDate, int crewLinkLineNo) {
		return flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode,flightDate,crewLinkLineNo);
	}

//	@Override
//	public List<Event> listEventBySameLoopIdFact(int crewLinkLineId) {
//		LinkLine thisLinkLine = linkLineMapper.getLinkLineByCrewLinkLineId(crewLinkLineId);
//		LinkLineEntity query = new LinkLineEntity();
//		query.setDutyCode(CrewConstant.DUTY_F);
//		query.setLoopIdFact(thisLinkLine.getLoopIdFact());
//		List<LinkLine> list =  linkLineMapper.listLinkLineBase(query);
//		List<Event> eList = new ArrayList<>();
//		for(LinkLine l : list ){
//			Event e = this.getEventByLinkLine(l);
//			eList.add(e);
//		}
//		return eList;
//	}
//	@Override
//	public List<Event> listEventNotHaveLoopIdFact(String dutyCode,Date flightDateStart, Date flightDateEnd) {
//		List<LinkLine> list  = linkLineMapper.listLinkLineBaseNotHaveLoopIdFact(dutyCode,flightDateStart, flightDateEnd);
//		ListSortUtil.sort(list, true, "flightDate","acLinkLine","td");
//		
//		List<Event> eList = new ArrayList<>();
//		for(LinkLine l : list ){
//			Event e = this.getEventByLinkLine(l);
//			eList.add(e);
//		}
//		return eList;
//	}
	
	/**
	 * 最高级别事务 isolation=Isolation.SERIALIZABLE
	 */
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER,isolation=Isolation.SERIALIZABLE)
	@Override
	public int getNewCrewLinkLineNo(String dutyCode, Date flightDate) {
		// 1.从连线序列生成器表中获取最大连线号
		Integer maxCrewLinkLine = linkLineMapper.getMaxCrewLinkLine(dutyCode, flightDate);
		boolean saveFlag = maxCrewLinkLine == null ? true : false;
		if (saveFlag) {
			maxCrewLinkLine = 1;
		}

		// 2.查询已经存在的连线号是否冲突
		List<Integer> maxCrewLinkLineHas = linkLineMapper.getMaxCrewLinkLineHas(dutyCode, flightDate);
		boolean hasFlag = false;
		for (Integer i : maxCrewLinkLineHas) {
			if (maxCrewLinkLine.equals(i)) {
				hasFlag = true;
			}
		}

		if (saveFlag) {
			linkLineMapper.insertMaxCrewLinkLine(dutyCode, flightDate, maxCrewLinkLine);
		} else {
			if (hasFlag) {
				linkLineMapper.updateMaxCrewLinkLine(dutyCode, flightDate, maxCrewLinkLine + 1);
			} else {
				linkLineMapper.updateMaxCrewLinkLine(dutyCode, flightDate, maxCrewLinkLine);
			}

		}

		if (hasFlag) {
			return getNewCrewLinkLineNo(dutyCode, flightDate);
		} else {
			return maxCrewLinkLine;
		}

	}
	@Override
	public ResponseResult<String> addFlightToLinkLineCk(int flightId,String dutyCode, Date flightDate, int crewLinkLineNo) {
		FlightInfo flightInfo = flightInfoMapper.selectByPrimaryKey(flightId);
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,dutyCode);

		boolean flag = true;
		StringBuffer sb = new StringBuffer();
		
		if(StringUtils.isNoneBlank(flightInfo.getFlgCs())
				|| StringUtils.equals(flightInfo.getFlgVr(), "VC")
				|| StringUtils.equals(flightInfo.getFlgVr(), "RC")
				|| StringUtils.equals(flightInfo.getAdjustType(), "0")
				|| StringUtils.equals(flightInfo.getAdjustType(), "b")
				){
			sb.append("该航班已经取消，");
			flag = false;
		}
		
//		if(flightInfo.getCrewLinklineNoF() != null && StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
//			sb.append("该航班已经拥有连线");
//			flag = false;
//		}
//		if(flightInfo.getCrewLinklineNoA() != null && StringUtils.equals(dutyCode, CrewConstant.DUTY_C)){
//			sb.append("该航班已经拥有连线");
//			flag = false;
//		}
//		if(flightInfo.getCrewLinklineNoA() != null && StringUtils.equals(dutyCode, CrewConstant.DUTY_A)){
//			sb.append("该航班已经拥有连线");
//			flag = false;
//		}
		
		//如果是新连线，则不需要
		if(linkLine != null){
//			if(!linkLine.getFlightDate().equals(flightInfo.getFlightDate())){
//				sb.append("航班与连线不是同一天，");
//				flag = false;
//			}
			if(!StringUtils.equals(flightInfo.getAcType(), linkLine.getAcType()) 
					&& StringUtils.isNotBlank(linkLine.getAcType())){
				sb.append("机型不一致，");
				flag = false;
			}
//			if(!StringUtils.equals(flightInfo.getAcReg(), linkLine.getAcReg())
//					&& StringUtils.isNotBlank(linkLine.getAcReg())){
//				sb.append("机号不一致，");
//				flag = false;
//			}
//			if(!StringUtils.equals(flightInfo.getAcLineLine(), linkLine.getAcLinkLine())
//					&& StringUtils.isNotBlank(linkLine.getAcLinkLine())){
//				sb.append("飞机连线不一致，");
//				flag = false;
//			}
//			if(!StringUtils.equals(flightInfo.getDorI(), linkLine.getDOrI())
//					&& StringUtils.isNotBlank(linkLine.getDOrI())){
//				sb.append("国内国际不同，");
//				flag = false;
//			}
		}
		
		//飞行时间判断
		/*
		 *  2名驾驶员报到时间在00:00-04:59或20:00-23:59，最大飞行时间8小时
			2名驾驶员报到时间在05:00-19:59，最大飞行时间9小时
			3名驾驶员最大飞行时间13小时（双机长）
			4名驾驶员最大飞行时间17小时（两套组）
			总结来说，就是总飞行时间不能超过17小时
		 */
		
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
			List<FlightInfo> flightInfoList = this.listFlightBySameTaskLoopFactSameFlightDate(dutyCode, flightDate, crewLinkLineNo);
			flightInfoList.add(flightInfo);//将本次要添加的航班添加到列表汇总
			int flightDurationSum = FlightDurationUtil.getFlightDuration(flightInfoList);
			if(flightDurationSum>17*60){
				sb.append("该任务环当日飞行时间超过17小时");
				flag = false;
			}
			
			ListSortUtil.sort(flightInfoList, true, "std");
			
			
			//任务环匹配
//			taskLoopFlightFactService.flightInfoTaskLoopFlightFactListInit(dutyCode,flightInfoList);
//			int durationEveryDay = DutyDurationUtil.getDutyDurationByFlightInfo(dutyCode, flightInfoList);
//			AirPlane airPlan =  airPlaneMapper.getAirPlane(flightInfo.getAcReg());
//			int restLevel = 0;
//			if(airPlan !=null ){
//				restLevel = airPlan.getRestLevel() == null ?0 :  airPlan.getRestLevel();
//			}
//			boolean dutyDurationCk  = true;
//			if(restLevel == 0 && durationEveryDay >14){
//				dutyDurationCk = false;
//			}
//			if(restLevel == 1 && durationEveryDay>20){
//				dutyDurationCk = false;
//			}if(restLevel == 2 && durationEveryDay>19){
//				dutyDurationCk = false;
//			}if(restLevel == 3 && durationEveryDay>18){
//				dutyDurationCk = false;
//			}
//			//boolean dutyDurationCk = DutyDurationUtil.dutyDurationCkEveryDayCore(durationEveryDay, flightInfoList.get(0), flightInfoList.size(),restLevel);
//			if(!dutyDurationCk){
//				sb.append("该任务环当日执勤期不符合局方规定");
//				flag = false;
//			}
		}
	

		
		
		if(flag){
			return ResponseResultBuilder.successResult();
		}else{
			return ResponseResultBuilder.errorResult(null, sb.toString(), "400");
		}
	}
	
	
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void addFlightToLinkLine(int flightId, String dutyCode, Date flightDate, int crewLinkLineNo,String taskLoopFact) {
		//查询航班信息
		FlightInfo flightInfo = flightInfoMapper.selectByPrimaryKey(flightId);
		
		List<FlightInfo> flightInfoHas = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		List<FlightInfo> flightAll  = new ArrayList<>();
		flightAll.add(flightInfo);
		if(CollectionUtils.isNotEmpty(flightInfoHas)){
			flightAll.addAll(flightInfoHas);
		}
		ListSortUtil.sort(flightAll, true, "std");
		
		//查询连线信息
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,dutyCode);
		boolean saveFlag = false;
		if(linkLine == null){
			linkLine = new LinkLine();
			saveFlag = true;
		}
		
		//构造连线信息
		linkLine.setDutyCode(dutyCode);
		linkLine.setFlightDate(flightDate);
		linkLine.setCrewLinkLineNo(crewLinkLineNo);
		linkLine.setConfirmFlag(false);
		//构造其他信息
		this.initLinkLine(linkLine, flightAll);
		
		
		//保存连线信息到各自的连线表
		//飞行连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
			if(flightInfo.getFlightDate().equals(flightDate)){
				if(saveFlag){
					linkLineFService.saveSelective(linkLine);
				}else{
					linkLineFService.updateByPrimaryKeySelective(linkLine);
				}
				//修改航班的连线信息
				flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_F, flightId, crewLinkLineNo);
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_F, flightId, taskLoopFact);
				//初始化、修改号位信息
//				int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_F, flightDate, crewLinkLineNo);
//				positionService.initPositionByCrewType(CrewConstant.DUTY_F, flightDate, crewLinkLineNo, crewType);
				
				
			}else{
				//如果航班和连线不再一天，则只修改任务环信息，不修改连线信息
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_F, flightId, taskLoopFact);
			}
		}
		//如果启用飞行连线同步客舱保卫连线，则同步执行 标记：LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA
		//客舱连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			if(flightInfo.getFlightDate().equals(flightDate)){
				LinkLine linkLineC = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,CrewConstant.DUTY_C);
				if(linkLineC == null){
					linkLineCService.saveSelective(linkLine);
				}else{
					linkLine.setCrewLinkLineId(linkLineC.getCrewLinkLineId());
					linkLineCService.updateByPrimaryKeySelective(linkLine);
				}
				//修改航班的连线信息
				flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_C, flightId, crewLinkLineNo);
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_C, flightId, taskLoopFact);
				//初始化、修改号位信息
//				int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_C, flightDate, crewLinkLineNo);
//				positionService.initPositionByCrewType(CrewConstant.DUTY_C, flightDate, crewLinkLineNo,crewType);
			}else{
				//如果航班和连线不再一天，则只修改任务环信息，不修改连线信息
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_C, flightId, taskLoopFact);
			}
		}
		
		//保卫连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_A) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			if(flightInfo.getFlightDate().equals(flightDate)){
				LinkLine linkLineA = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,CrewConstant.DUTY_A);
				if(linkLineA == null){
					linkLineAService.saveSelective(linkLine);
				}else{
				
					linkLine.setCrewLinkLineId(linkLineA.getCrewLinkLineId());
					linkLineAService.updateByPrimaryKeySelective(linkLine);
				}
				//修改航班的连线信息
				flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_A, flightId, crewLinkLineNo);
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_A, flightId, taskLoopFact);
				//初始化、修改号位信息
//				int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_A, flightDate, crewLinkLineNo);
//				positionService.initPositionByCrewType(CrewConstant.DUTY_A, flightDate, crewLinkLineNo, crewType);
			}else{
				//修改航班任务环信息
				flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_A, flightId, taskLoopFact);
			}
			
		}
	}


	private LinkLine initLinkLine(LinkLine linkLine,List<FlightInfo> flightAll){
		if(CollectionUtils.isEmpty(flightAll)){
			linkLine.setFlightCom("");
			linkLine.setFlightVoyage("");
			linkLine.setFlightVoyageCode("");
			linkLine.setLinkDepartureAirport("");
			linkLine.setTd(linkLine.getFlightDate());
			linkLine.setLinkArrivalAirport("");
			linkLine.setTa(linkLine.getFlightDate());
			linkLine.setAcType("");
			linkLine.setAcReg("");
			linkLine.setAcLinkLine("");
			linkLine.setDOrI("");
			linkLine.setPOrC("");
			linkLine.setFlightType("");
			linkLine.setFlyHours(0);
			linkLine.setLoopVoyage("");
			linkLine.setLoopVoyageCode("");
			return linkLine;
		}
		String flightCom = flightInfoService.getFlightCom(flightAll);
		linkLine.setFlightCom(flightCom);
		String flightVoyage = 	airprotService.getShortCityLine(flightAll,null);
		linkLine.setFlightVoyage(flightVoyage);
		String flightVoyageCode = airprotService.getAirportCodeLine(flightAll);
		linkLine.setFlightVoyageCode(flightVoyageCode);
		
		FlightInfo flightInfoStart = flightAll.get(0);
		FlightInfo flightInfoEnd = flightAll.get(flightAll.size()-1);
		
		linkLine.setLinkDepartureAirport(flightInfoStart.getDepartureAirport());
		linkLine.setTd(flightInfoStart.getStd());
		linkLine.setLinkArrivalAirport(flightInfoEnd.getArrivalAirport());
		linkLine.setTa(flightInfoEnd.getSta());
		linkLine.setAcType(flightInfoStart.getAcType());
		linkLine.setAcReg(flightInfoStart.getAcReg());
		linkLine.setAcLinkLine(flightInfoStart.getAcLineLine());
		linkLine.setDOrI(flightInfoStart.getDorI());
		linkLine.setPOrC(flightInfoStart.getPorC());
		linkLine.setFlightType(flightInfoStart.getFlightType());
		
		//计划飞行时间
		int flyHours = flightInfoService.getFlightDuration(flightAll);
		linkLine.setFlyHours(flyHours);
		
		
		//任务环匹配
		taskLoopFlightFactService.flightInfoTaskLoopFlightFactListInit(linkLine.getDutyCode(),flightAll);

		//计算该连线的执勤期--计划
		int dutyHours =  DutyDurationUtil.getDutyDurationByFlightInfo(linkLine.getDutyCode(), flightAll);
		linkLine.setDutyHours(dutyHours);
		
		//任务环描述信息构造
		List<FlightInfo> flightInfoForSameLoop  = this.listFlightBySameTaskLoopFact(linkLine.getDutyCode(), linkLine.getFlightDate(), linkLine.getCrewLinkLineNo());
		
		Set<FlightInfo> flightInfoSet = new HashSet<>();
		flightInfoSet.addAll(flightInfoForSameLoop);
		flightInfoSet.addAll(flightAll);
		
		List<FlightInfo> flightInfoUnion = new ArrayList<>(flightInfoSet);
		ListSortUtil.sort(flightInfoUnion, true, "std");
		
		String loopVoyage = 	airprotService.getShortCityLine(flightInfoUnion,null);
		linkLine.setLoopVoyage(loopVoyage);
		String loopVoyageCode = airprotService.getAirportCodeLine(flightInfoUnion);
		linkLine.setLoopVoyageCode(loopVoyageCode);
		
		
		return linkLine;
	}
	@Override
	public List<EventForFlight> listEventForFlight(String dutyCode, Date flightDate) {
		FlightInfo fQuery = new FlightInfo();
		fQuery.setFlightDate(flightDate);
		List<FlightInfo> list = flightInfoMapper.listFlightInfo(fQuery);
		return this.getEventForFlightList(dutyCode, list);
	}
	
	/**
	 *  私有方法，将FlightInfo 转换成EventForFlight
	 * @param list
	 * @return
	 */
	private List<EventForFlight> getEventForFlightList(String dutyCode,List<FlightInfo> list){
		List<EventForFlight> eList = new ArrayList<>();
		List<Select2> cityAbbrList  = select2Service.getAirportCityAbbr();
		if(StringUtils.equals(CrewConstant.DUTY_F, dutyCode)){
			ListSortUtil.sort(list, true, "flightDate","taskLoopFactF","std");
		}
		if(StringUtils.equals(CrewConstant.DUTY_C, dutyCode)){
			ListSortUtil.sort(list, true, "flightDate","taskLoopFactC","std");
		}
		if(StringUtils.equals(CrewConstant.DUTY_A, dutyCode)){
			ListSortUtil.sort(list, true, "flightDate","taskLoopFactA","std");
		}
		
		for(int i = 0;i<list.size();i++){
			FlightInfo f = list.get(i);
			//如果没有crewlinklineno，就没有必要组装，也没有必要返回给前台
			if(this.getCrewLinkLineNo(f, dutyCode) == null){
				continue;
			}
			
			EventForFlight e = new EventForFlight();
			e.setId(f.getFlightId().toString());
			
			e.setResourceId(String.valueOf(this.getCrewLinkLineNo(f, dutyCode)));
			e.setTaskLoopFact(this.getTaskLoopFact(f, dutyCode));
			e.setRestTime(this.getArrivalAirportRestTime(f, dutyCode));
			e.setFlightDate(f.getFlightDate());
			e.setStart(f.getStd());
			e.setEnd(f.getSta());
			e.setFlightNo(f.getFlightNo().replaceAll("ABC", ""));
			
			String airPortCityName =  select2Service.getText(cityAbbrList, f.getDepartureAirport())
					+ select2Service.getText(cityAbbrList, f.getArrivalAirport());

			e.setAirPortCityName(airPortCityName);
			e.setTitle(e.getAirPortCityName()+e.getFlightNo());
			
			//同一天,同一个任务环，下一个航班如果机序不同，则提示换飞机
			FlightInfo fNext = i<list.size()-1?list.get(i+1):null; 
			if(fNext !=null){
				if(f.getFlightDate().equals(fNext.getFlightDate())
						&& StringUtils.isNoneBlank(this.getTaskLoopFact(f, dutyCode))
						&& StringUtils.equals(this.getTaskLoopFact(f, dutyCode), this.getTaskLoopFact(fNext, dutyCode))
						){
					e.setChangeAcFlag(true);
				}
			}
		
			eList.add(e);
		}
		return eList;
	}
	
	@Override
	public List<FlightInfo> listFlightBySameTaskLoopFact(String dutyCode,Date flightDate,int crewLinkLineNo) {
		List<FlightInfo> list = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		Set<String> set = new HashSet<>();
		for(FlightInfo f: list){
			set.add(this.getTaskLoopFact(f, dutyCode));
		}
		
		if(set.size()==0){
			return list;
		}
		
		List<FlightInfo> listHasTaskLoopFactAll = new ArrayList<>();
		for(String taskLoopFact : set){
			List<FlightInfo> listHasTaskLoopFact = flightInfoMapper.listFlightInfoByTaskLoopFact(dutyCode, taskLoopFact);
			listHasTaskLoopFactAll.addAll(listHasTaskLoopFact);
		}
		
		return listHasTaskLoopFactAll;
	}
	@Override
	public ResponseResult<String> removeFlightFromLinkLineCk(int flightId, String dutyCode, Date flightDate,
			int crewLinkLineNo) {
		FlightInfo flightInfo = flightInfoMapper.selectByPrimaryKey(flightId);

		boolean flag = true;
		StringBuffer sb = new StringBuffer();
		if(flightInfo == null){
			sb.append("该航班不存在");
			flag = false;
			return ResponseResultBuilder.errorResult(null, sb.toString(), "400"); 
		}else{
			Integer flightCrewLinkLineNo = this.getCrewLinkLineNo(flightInfo, dutyCode);
			if(flightCrewLinkLineNo==null){
				sb.append("该航班没有连线");
				flag = false;
			}
			
		}
		
		if(flag){
			return ResponseResultBuilder.successResult();
		}else{
			return ResponseResultBuilder.errorResult(null, sb.toString(), "400");
		}
	}
	
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void removeFlightFromLinkLine(int flightId, String dutyCode) {
		//查询航班信息
		FlightInfo flightInfo = flightInfoMapper.selectByPrimaryKey(flightId);
		Date flightDate = flightInfo.getFlightDate();
		Integer crewLinkLineNo = this.getCrewLinkLineNo(flightInfo, dutyCode);
		if(crewLinkLineNo == null){
			return;
		}
				
		//查询航班信息
		List<FlightInfo> flightInfoHas = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		List<FlightInfo> flightAll  = new ArrayList<>();
		for(FlightInfo f : flightInfoHas){
			if(!f.getFlightId().equals(flightId)){
				flightAll.add(f);
			}
		}
		ListSortUtil.sort(flightAll, true, "std");
		
		//查询连线信息
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,dutyCode);
		boolean saveFlag = false;
		if(linkLine == null){
			linkLine = new LinkLine();
			saveFlag = true;
		}
		
		//构造连线信息
		linkLine.setDutyCode(dutyCode);
		linkLine.setFlightDate(flightDate);
		linkLine.setCrewLinkLineNo(crewLinkLineNo);
		linkLine.setConfirmFlag(false);
		//构造其他信息
		this.initLinkLine(linkLine, flightAll);
		
		
		//保存连线信息到各自的连线表
		//飞行连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
			if(saveFlag){
				linkLineFService.saveSelective(linkLine);
			}else{
				linkLineFService.updateByPrimaryKeySelective(linkLine);
			}
			//修改航班的连线信息
			flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_F, flightId, -1);
			//修改航班任务环信息
			flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_F, flightId, null);
			
			//初始化、修改号位信息
//			int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_F, flightDate, crewLinkLineNo);
//			positionService.initPositionByCrewType(CrewConstant.DUTY_F, flightDate, crewLinkLineNo,crewType);
		}
		//如果启用飞行连线同步客舱保卫连线，则同步执行 标记：LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA
		//客舱连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			
			if(saveFlag){
				linkLineCService.saveSelective(linkLine);
			}else{
				LinkLine linkLineC = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,CrewConstant.DUTY_C);
				linkLine.setCrewLinkLineId(linkLineC.getCrewLinkLineId());
				linkLineCService.updateByPrimaryKeySelective(linkLine);
			}
			//修改航班的连线信息
			flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_C, flightId, -1);
			//修改航班任务环信息
			flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_C, flightId, null);
			//初始化、修改号位信息
//			int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_C, flightDate, crewLinkLineNo);
//			positionService.initPositionByCrewType(CrewConstant.DUTY_C, flightDate, crewLinkLineNo, crewType);
		}
		
		//保卫连线
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_A) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			
			
			if(saveFlag){
				linkLineAService.saveSelective(linkLine);
			}else{
				LinkLine linkLineA = linkLineMapper.getLinkLine(flightDate,crewLinkLineNo,CrewConstant.DUTY_A);
				linkLine.setCrewLinkLineId(linkLineA.getCrewLinkLineId());
				linkLineAService.updateByPrimaryKeySelective(linkLine);
			}
			//修改航班的连线信息
			flightInfoService.updateCrewLinkLineNo(CrewConstant.DUTY_A, flightId, -1);
			//修改航班任务环信息
			flightInfoService.updateTaskLoopFact(CrewConstant.DUTY_A, flightId, null);
			//初始化、修改号位信息
//			int  crewType = positionService.buildCrewTypeIdByLinkLine(CrewConstant.DUTY_A, flightDate, crewLinkLineNo);
//			positionService.initPositionByCrewType(CrewConstant.DUTY_A, flightDate, crewLinkLineNo, crewType);
		}
		
	}
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void moveFlight(int flightId, String dutyCode, Date flightDate, int crewLinkLineNoOld,
			int crewLinkLineNoNew) {
		this.removeFlightFromLinkLine(flightId, dutyCode);
		List<FlightInfo> flightInfoListOld = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNoOld);
		String taskLoopFactOld = null;
		if(CollectionUtils.isNotEmpty(flightInfoListOld)){
			taskLoopFactOld = this.getTaskLoopFact(flightInfoListOld.get(0), dutyCode);
		}
		
		List<FlightInfo> flightInfoNew = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNoNew);
		String taskLoopFactNew = null;
		if(CollectionUtils.isNotEmpty(flightInfoNew)){
			taskLoopFactNew = this.getTaskLoopFact(flightInfoNew.get(0), dutyCode);
		}
		if(StringUtils.isBlank(taskLoopFactNew)){
			taskLoopFactNew = taskLoopFactOld;
		}
	
		
		this.addFlightToLinkLine(flightId, dutyCode, flightDate, crewLinkLineNoNew,taskLoopFactNew);
	}
	@Override
	public boolean flightDateCk(Date flightDateStart, Date flightDateEnd) {
		DateTime now = DateTime.now().withTimeAtStartOfDay();
		DateTime start = new DateTime(flightDateStart).withTimeAtStartOfDay();
		DateTime end = new DateTime(flightDateEnd).withTimeAtStartOfDay();
		boolean flag = true;
		for(DateTime temp = start; !temp.isAfter(end) ;temp = temp.plusDays(1)){
			DateTime flightDateTime = new DateTime(temp).withTimeAtStartOfDay();
			Duration duration = new Duration(now, flightDateTime);
			long dayDiff  = duration.getStandardDays();
			if(dayDiff < LinkLineConstant.ABLE_CHANGE_DAY_DIFF){
				flag =  false;
			}
		}
		
		return flag;
	}
	@Override
	public ResponseResult<String> deleteLinkLineCk(String dutyCode,Date flightDate, int crewLinkLineNo) {
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate, crewLinkLineNo, dutyCode);
		List<FlightInfo> flightInfoHas = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		boolean flag = true;
		StringBuffer sb = new StringBuffer();
		if(linkLine == null){
			sb.append("该连线不存在，请核对数据后再执行删除");
			flag = false;

		}
		if(CollectionUtils.isNotEmpty(flightInfoHas)){
			sb.append("该连线下存在航班，请将航班拆除后，再删除连线");
			flag = false;
		}
		
		if(flag){
			return ResponseResultBuilder.successResult();
		}else{
			return ResponseResultBuilder.errorResult(null, sb.toString(), "400");
		}
	}
	
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void deleteLinkLine(String dutyCode, Date flightDate, int crewLinkLineNo) {
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate, crewLinkLineNo, dutyCode);
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
			linkLineFService.deleteByPrimaryKey(linkLine.getCrewLinkLineId());
			positionService.deleteByFlightDate(flightDate,crewLinkLineNo, CrewConstant.DUTY_F);
		}
		
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			linkLineCService.deleteByPrimaryKey(linkLine.getCrewLinkLineId());
			positionService.deleteByFlightDate(flightDate, crewLinkLineNo, CrewConstant.DUTY_C);
		}
		
		if(StringUtils.equals(dutyCode, CrewConstant.DUTY_A) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
			linkLineAService.deleteByPrimaryKey(linkLine.getCrewLinkLineId());
			positionService.deleteByFlightDate(flightDate, crewLinkLineNo, CrewConstant.DUTY_A);
		}
	}
	@Override
	public List<FlightInfo> listFlightNotHaveTaskLoopFact(String dutyCode, Date flightDateStart,
			Date flightDateEnd) {
		List<FlightInfo> list = flightInfoMapper.listFlightInfoByDateTimeRange(flightDateStart,flightDateEnd);
		List<FlightInfo> listNotHaveTaskLoopFact  = new ArrayList<>();
		for(FlightInfo f : list){
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F) && StringUtils.isBlank(f.getTaskLoopFactF())){
				listNotHaveTaskLoopFact.add(f);
			}
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C) && StringUtils.isBlank(f.getTaskLoopFactC())){
				listNotHaveTaskLoopFact.add(f);
			}
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_A) && StringUtils.isBlank(f.getTaskLoopFactA())){
				listNotHaveTaskLoopFact.add(f);
			}
		}
		return listNotHaveTaskLoopFact;
	}
	@Override
	public void createNewTaskLoopFact(String dutyCode, Date flightDate, Integer crewLinkLineNo) {
		List<FlightInfo> flightInfoList = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		String taskLoopFact = taskLoopFlightFactService.buildTaskLoopFact();
		for(FlightInfo flightInfo : flightInfoList){
			 taskLoopFlightFactService.saveOrUpdateTaskLoopFact( dutyCode, flightInfo.getFlightDate() ,flightInfo.getFlightId(),  taskLoopFact);
		}
		
	}
	@Override
	public void moveTaskLoop(String dutyCode, Date flightDate, Integer crewLinkLineNo, int crewLinkLineNoMoveTo) {
		List<FlightInfo> listMoveTo = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNoMoveTo);
		if(CollectionUtils.isNotEmpty(listMoveTo));{
			String taskLoopFact = taskLoopFlightFactService.getTaskLoopFlightFact(dutyCode, listMoveTo.get(0).getFlightId()).getTaskLoopFact();		
					
			List<FlightInfo> list = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
			for(FlightInfo flightInfo : list){
				 taskLoopFlightFactService.saveOrUpdateTaskLoopFact( dutyCode, flightInfo.getFlightDate() ,flightInfo.getFlightId(),  taskLoopFact);
			}
		}	
	}
	
	@Override
	public LinkLine getOrInitLinkLine(int flightId, String dutyCode, Date flightDate, int crewLinkLineNo) {
		List<FlightInfo> flightInfoHas = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		String taskLoopFact = null;
		if(CollectionUtils.isNotEmpty(flightInfoHas)){
			taskLoopFact = this.getTaskLoopFact(flightInfoHas.get(0), dutyCode);
		}
		FlightInfo flightInfo = flightInfoMapper.selectByPrimaryKey(flightId);
		LinkLine linkLine = new LinkLine();
		linkLine.setFlightDate(flightInfo.getFlightDate());
		linkLine.setDutyCode(dutyCode);
		linkLine.setTaskLoopFact(taskLoopFact);
		
		if(flightInfo.getFlightDate().equals(flightDate)){
			linkLine.setCrewLinkLineNo(crewLinkLineNo);
		}else{
		
			//flightDate对应的连线
			List<FlightInfo> flightInfoList =  flightInfoMapper.listFlightInfoByTaskLoopFact(dutyCode, taskLoopFact);
			if(CollectionUtils.isNotEmpty(flightInfoList)){ 
				ListSortUtil.sort(flightInfoList, true, "std");
			}
			int nextcrewLinkLineNo = 0;
			for(FlightInfo f : flightInfoList){
				if(f.getFlightDate().equals(flightInfo.getFlightDate())){
					nextcrewLinkLineNo = this.getCrewLinkLineNo(f, dutyCode);	
				}
			}
			if(nextcrewLinkLineNo == 0){
				nextcrewLinkLineNo = this.getNewCrewLinkLineNo(dutyCode,flightInfo.getFlightDate());
			}
			linkLine.setCrewLinkLineNo(nextcrewLinkLineNo);
		}
		
		return linkLine;
	}
	@Override
	public ResponseResult<String> deleteTaskLoopCk(String dutyCode, Date flightDate, Integer crewLinkLineNo) {
		List<FlightInfo> flightInfoList = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		boolean flag = true;
		for(FlightInfo f : flightInfoList){
			boolean ckDay = this.flightDateCk(f.getFlightDate(), f.getFlightDate());
			if(!ckDay){
				flag =false;
			}
		}
		if(flag){
			return ResponseResultBuilder.successResult();
		}else{
			return ResponseResultBuilder.errorResult(null, "该任务环下有航班不能修改", "400");
		}
	}
	
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void deleteTaskLoop(String dutyCode, Date flightDate, Integer crewLinkLineNo) {

		List<FlightInfo> flightInfoList = flightInfoMapper.listFlightInfoByCrewLinkLineNo(dutyCode, flightDate, crewLinkLineNo);
		Set<String> flightDateAndCrewLinkLineNoSet = new HashSet<>();
	
		for(FlightInfo f : flightInfoList){
			this.removeFlightFromLinkLine(f.getFlightId(), dutyCode);
			
			//构造连线
			Integer crewLinkLineNoFlightInfo = this.getCrewLinkLineNo(f, dutyCode);
			flightDateAndCrewLinkLineNoSet.add(TimeUtil.transDate(f.getFlightDate())+"----"+crewLinkLineNoFlightInfo);
			
		}
		
		//2.删除连线
		for(String flightDateAndCrewLinkLineNo : flightDateAndCrewLinkLineNoSet){
			String[] array = flightDateAndCrewLinkLineNo.split("----");
			Date flightDateTemp = TimeUtil.getDateByYyyyMM(array[0]);
			Integer crewLinkLineNoTemp = Integer.valueOf(array[1]);
			this.deleteLinkLine(dutyCode, flightDateTemp, crewLinkLineNoTemp);	
		}
		
	}
	
	private String getTaskLoopFact(FlightInfo f,String dutyCode){
		if(StringUtils.equals(CrewConstant.DUTY_F, dutyCode)){
			return f.getTaskLoopFactF();
		}else if(StringUtils.equals(CrewConstant.DUTY_C, dutyCode)){
			return f.getTaskLoopFactC();
		}else if(StringUtils.equals(CrewConstant.DUTY_A, dutyCode)){
			return f.getTaskLoopFactA();
		}else{
			return null;
		}
	}
	
	@Override
	public Integer getCrewLinkLineNo(FlightInfo f,String dutyCode){
		if(StringUtils.equals(CrewConstant.DUTY_F, dutyCode)){
			return f.getCrewLinklineNoF();
		}else if(StringUtils.equals(CrewConstant.DUTY_C, dutyCode)){
			return f.getCrewLinklineNoC();
		}else if(StringUtils.equals(CrewConstant.DUTY_A, dutyCode)){
			return f.getCrewLinklineNoA();
		}else{
			return null;
		}
	}
	
	
	private Integer getArrivalAirportRestTime(FlightInfo f,String dutyCode){
		if(StringUtils.equals(CrewConstant.DUTY_F, dutyCode)){
			return f.getArrivalAirportRestTimeF();
		}else if(StringUtils.equals(CrewConstant.DUTY_C, dutyCode)){
			return f.getArrivalAirportRestTimeC();
		}else if(StringUtils.equals(CrewConstant.DUTY_A, dutyCode)){
			return f.getArrivalAirportRestTimeA();
		}else{
			return null;
		}
	}
	
	/**
	 * 确认逻辑：
	 * 1.当天没有未组连线的航班
	 * 2.每个航班的任务环是完整的（基地出、基地回）
	 * 3.任务环中的航班首位相连，时间不能冲突
	 */
	@Override
	public ResponseResult<String> confirmCk(String dutyCode, Date flightDate) {
		boolean flag = true;
		StringBuffer sb = new StringBuffer();
		
		// 1.当天没有未组连线的航班
		List<FlightInfo> flightInfoList = this.listFlightNotHaveTaskLoopFact(dutyCode, flightDate, flightDate);
		if(CollectionUtils.isNotEmpty(flightInfoList)){
			sb.append("存在未组航班"+BaseConstant.BR);
			flag = false;
		}
		
		List<Resource> resourceList = this.listResource(dutyCode, flightDate);
		for(Resource r : resourceList){
			int crewLinkLineNo = Integer.valueOf(r.getId());
			List<FlightInfo> sameTaskFlightInfoList = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
			if(CollectionUtils.isEmpty(sameTaskFlightInfoList)){
				continue;
			}
			ListSortUtil.sort(sameTaskFlightInfoList, true, "std");
			
			//2.每个航班的任务环是完整的（基地出、基地回）
			FlightInfo flightInfoStart = sameTaskFlightInfoList.get(0);
			if(!foundationService.isBase(flightInfoStart.getDepartureAirport(), dutyCode)){
				sb.append("连线【"+r.getId()+"】："+getFlightInfoDesc(flightInfoStart)+"起飞机场不是基地"+BaseConstant.BR);
				flag = false;
			}
			
			FlightInfo flightInfoEnd = sameTaskFlightInfoList.get(sameTaskFlightInfoList.size()-1);
			if(!foundationService.isBase(flightInfoEnd.getArrivalAirport(), dutyCode)){
				sb.append("连线【"+r.getId()+"】："+getFlightInfoDesc(flightInfoEnd)+"落地机场不是基地"+BaseConstant.BR);
				flag = false;
			}
			
			//3.任务环中的航班首位相连，时间不能冲突
			List<DateTimeRange> dtrList = new ArrayList<>();
			for(int i = 0; i< sameTaskFlightInfoList.size() ; i++){
				FlightInfo f = sameTaskFlightInfoList.get(i);
				if(i+1<sameTaskFlightInfoList.size()){
					FlightInfo next = sameTaskFlightInfoList.get(i+1);
					if(!StringUtils.equals(f.getArrivalAirport(),next.getDepartureAirport())){
						sb.append("连线【"+r.getId()+"】："+getFlightInfoDesc(f)+"机场不连续"+BaseConstant.BR);
						flag = false;
					}
				}
				
				DateTimeRange dtr = new DateTimeRange(f.getStd(),f.getSta());
				dtrList.add(dtr);
			}
			if(DateTimeRangeUtil.isIntersection(dtrList)){
				sb.append("连线【"+r.getId()+"】：已组航班时间冲突"+BaseConstant.BR);
				flag = false;
			}		
		}
		if(flag){
			return ResponseResultBuilder.successResult();
		}else{
			return ResponseResultBuilder.errorResult(null, sb.toString(), "400");
		}
	}

	/**
	 * 将航班信息文字化
	 * @param flightInfo
	 * @return
	 */
	private String getFlightInfoDesc(FlightInfo flightInfo){
		StringBuffer sb = new StringBuffer();
		sb.append(TimeUtil.transDate(flightInfo.getFlightDate()) + " ");
		sb.append(flightInfo.getFlightNo()+ " ");
		sb.append(flightInfo.getDepartureAirport()+"-" +flightInfo.getArrivalAirport());
		return sb.toString();
	}
	
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void confirm(String dutyCode, Date flightDate) {
		List<Resource> resourceList = this.listResource(dutyCode, flightDate);
		for(Resource r : resourceList){
			LinkLine linkLine = new LinkLine();
			linkLine.setCrewLinkLineId(Integer.valueOf(r.getId()));
			linkLine.setConfirmFlag(true);
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
				linkLineFService.updateByPrimaryKeySelective(linkLine);
			}
			//如果启用飞行连线同步客舱保卫连线，则同步执行 标记：LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
				linkLineCService.updateByPrimaryKeySelective(linkLine);
			}
			if(StringUtils.equals(dutyCode, CrewConstant.DUTY_A) || LinkLineConstant.LINKLINE_SYNCHRO_F_TO_CA){
				linkLineAService.updateByPrimaryKeySelective(linkLine);
			}
			
		}
		
	}
	@Transactional(transactionManager=PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void badRoute(String dutyCode, Date flightDate, Integer crewLinkLineNo, Boolean badRoute) {
		List<FlightInfo> list = this.listFlight(dutyCode, flightDate, crewLinkLineNo);
		for(FlightInfo f : list){
			taskLoopFlightFactService.updateBadRoute(dutyCode, f.getFlightId(), badRoute);
		}		
	}
	@Override
	public TaskLoop getTaskLoopInfo(String dutyCode, Date flightDate, Integer crewLinkLineNo) {
		List<TaskLoopFlightFact>  list= taskLoopFlightFactService.listTaskLoopFlightFactByCrewLinkLine(dutyCode, flightDate, crewLinkLineNo);
		boolean badRoute = false;
		int minMale = 0;
		boolean internationalTimeZoneMore6 = false;
		Integer crewTypeId = -1;
		for(TaskLoopFlightFact tlff : list){
			if(tlff.getBadRoute() != null && tlff.getBadRoute() == true){
				badRoute = true;
			}
			
			if(tlff.getMinMale() != null && tlff.getMinMale()>minMale){
				minMale = tlff.getMinMale();
			}
			
			if(tlff.getInternationalTimeZoneMore6() != null && tlff.getInternationalTimeZoneMore6() == true){
				internationalTimeZoneMore6 = true;
			}
			
			if(tlff.getCrewTypeId() !=null && tlff.getCrewTypeId() > 0){
				crewTypeId = tlff.getCrewTypeId();
			}
		}
		TaskLoop tl = new TaskLoop();
		tl.setBadRoute(badRoute);
		tl.setMinMale(minMale);
		tl.setInternationalTimeZoneMore6(internationalTimeZoneMore6);
		if(crewTypeId !=null && crewTypeId>0 ){
			tl.setCrewNumberType(crewTypeId.toString());
		}
		
		return tl;
	}
	
	@Override
	public void minMale(String dutyCode, Date flightDate, Integer crewLinkLineNo, Integer minMale) {
		List<FlightInfo> list = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		for(FlightInfo f : list){
			taskLoopFlightFactService.updateMinMale(dutyCode, f.getFlightId(), minMale);
		}
		
	}
	@Override
	public void internationalTimeZoneMore6(String dutyCode, Date flightDate, Integer crewLinkLineNo,
			Boolean internationalTimeZoneMore6) {
		List<FlightInfo> list = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		for(FlightInfo f : list){
			taskLoopFlightFactService.updateInternationalTimeZoneMore6(dutyCode, f.getFlightId(), internationalTimeZoneMore6);
		}
		
		
	}
	@Override
	public List<FlightInfo> listFlightBySameTaskLoopFactSameFlightDate(String dutyCode, Date flightDate,
			int crewLinkLineNo) {
		List<FlightInfo> list = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		if(CollectionUtils.isEmpty(list)){
			return new ArrayList<>();
		}
		List<FlightInfo> sameDayList = new ArrayList<>();
		for(FlightInfo f : list){
			if(flightDate.equals(f.getFlightDate())){
				sameDayList.add(f);
			}
		}
		return sameDayList;
	}
	@Override
	public void updateCrewTypeId(String dutyCode, Date flightDate, Integer crewLinkLineNo, Integer crewType) {
		List<FlightInfo> list = this.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		for(FlightInfo f : list){
			taskLoopFlightFactService.updateCrewTypeId(dutyCode, f.getFlightId(), crewType);
			
			
			//2.根据机组几人制，更新连线上的号位人数
			Integer crewLinkLineNoEveryOne = flightInfoService.getCrewLinkLineNo(f, dutyCode);
			positionService.initPositionByCrewType(dutyCode, flightDate, crewLinkLineNoEveryOne,crewType);
		}
		

		
	}
	
}
